using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Threading;
using System.Diagnostics;
using System.Collections;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Net.Sockets;
using BrainTechLLC;

namespace Mud.EmlenMudMain
{
    [Serializable]
    public class OldSchoolMobPrototyes
    {
        public OldSchoolMobPrototyes() { }
        public void ReadOldMobileFormat(StreamReader sr, int vnum, AreaData area)
        {
            MobPrototype pMobIndex = new MobPrototype();
            pMobIndex.ObjCreationPoints = 0;
            pMobIndex.Vnum = vnum;
            pMobIndex.area = area;
            pMobIndex.AttackName = "";
            pMobIndex.Mobprototypename = "";
            pMobIndex.Short_descr = "";
            pMobIndex.Long_descr = "";
            pMobIndex.Description = "";
            pMobIndex.Script_fn = "";
            pMobIndex.Mobtype = MobTypes.HUMAN;
            pMobIndex.GuardClan = "";
            pMobIndex.GuardSect = "";
            pMobIndex.Hpmult = 10;
            pMobIndex.Yeller_number = 0;
            pMobIndex.MaxInWorld = 5;
            pMobIndex.Height = -1;
            pMobIndex.MobGuards = -1;
            pMobIndex.PrototypeBehaviors = 0;

            pMobIndex.PrototypeEffects = 0;
            pMobIndex.Alignment = 0;
            pMobIndex.Money = 0;
            pMobIndex.Sex = 0;

            pMobIndex.Armcls = 101;
            pMobIndex.AttackRaces = 0;
            pMobIndex.VnumAltersInto = 0;
            pMobIndex.MobGuards = -1;
            pMobIndex.ExtraHitroll = 0;
            pMobIndex.ExtraDamageroll = 0;
            pMobIndex.ExtraDodgeBonus = 0;
            pMobIndex.ExtraParryBonus = 0;
            char[] spc = new char[1];
            spc[0] = ' ';

            while (sr.EndOfStream == false)
            {
                string szLine = sr.ReadLine().Trim();
                string[] rgsz = szLine.Split(spc, 2, StringSplitOptions.RemoveEmptyEntries);

                if (szLine == "End")
                {
                    EmlenMud.WorldTemplates.AllMobPrototypes.Add(vnum, pMobIndex);
                    if (pMobIndex.Mobprototypename == "")
                        pMobIndex.Mobprototypename = "(no name)";
                    if (pMobIndex.Short_descr == "")
                        pMobIndex.Short_descr = "(no short desc)";
                    if (pMobIndex.Long_descr == "")
                        pMobIndex.Long_descr = "(no long desc)\n\r";
                    if (pMobIndex.Description == "")
                        pMobIndex.Description = "(no description)";
                    area.MobPrototypesBelongingToArea.Add(pMobIndex);
                    return;
                }

                string szWord = rgsz[0];

                if (szWord == "Attackmsg")
                {
                    pMobIndex.AttackName = rgsz[1].TrimEnd('~');
                    continue;
                }
                if (szWord == "AClan2") { pMobIndex.GuardSect = rgsz[1]; continue; }
                if (szWord == "AClan") { pMobIndex.GuardClan = rgsz[1]; continue; }
                if (szWord == "ActBits") { pMobIndex.PrototypeBehaviors = (ActionsAndBehavior)Convert.ToInt32(rgsz[1]); continue; }
                if (szWord == "ActBits3")
                {
                    Int64 tmp = (Convert.ToInt64(rgsz[1]) << 32);
                    pMobIndex.PrototypeBehaviors |= (ActionsAndBehavior)tmp;
                    continue;
                }
                if (szWord == "AYeller") { pMobIndex.Yeller_number = Convert.ToInt32(rgsz[1]); continue; }
                if (szWord == "AMax") { pMobIndex.MaxInWorld = Convert.ToInt32(rgsz[1]); continue; }
                if (szWord == "AWillhelp") { pMobIndex.Will_help = Convert.ToInt32(rgsz[1]); continue; }
                if (szWord == "ActBits4")
                {
                    int tmp = (Convert.ToInt32(rgsz[1]));
                    if ((tmp & 0x00000800) != 0)
                    { // MOBSWITCH
                        pMobIndex.PrototypeBehaviors |= ActionsAndBehavior.MOBSWITCH;
                    }
                    if ((tmp & 0x00001000) != 0)
                    { // FASTHUNT
                        pMobIndex.PrototypeBehaviors |= ActionsAndBehavior.FASTHUNT;
                    }
                    if ((tmp & 0x00002000) != 0)
                    { // SOLOYELL 
                        pMobIndex.PrototypeBehaviors |= ActionsAndBehavior.SOLOYELL;
                    }
                    if ((tmp & 0x00004000) != 0)
                    { // STAYOFFROAD 
                        pMobIndex.PrototypeBehaviors |= ActionsAndBehavior.STAYOFFROAD;
                    }
                    if ((tmp & 0x00008000) != 0)
                    { // KILLALLONE
                        pMobIndex.PrototypeBehaviors |= ActionsAndBehavior.KILLALLONE;
                    }
                    if ((tmp & 0x00010000) != 0)
                    { // KILLALLTWO
                        pMobIndex.PrototypeBehaviors |= ActionsAndBehavior.KILLALLTWO;
                    }
                    if ((tmp & 0x00020000) != 0)
                    { // KILLMEVIL
                        pMobIndex.PrototypeBehaviors |= ActionsAndBehavior.KILLMEVIL;
                    }
                    if ((tmp & 0x00040000) != 0)
                    { // KILLMGOOD 
                        pMobIndex.PrototypeBehaviors |= ActionsAndBehavior.KILLMGOOD;
                    }
                    continue;
                }
                if (szWord == "Affect_By") { pMobIndex.PrototypeEffects = (long)Convert.ToInt32(rgsz[1]); continue; }
                if (szWord == "AffectTWO")
                {
                    Int64 i64 = Convert.ToInt64(rgsz[1]);
                    Int64 i64Shifted = i64 << 32;
                    //pMobIndex.more_affected_by = (EffectType2) 
                    pMobIndex.PrototypeEffects |= (long)i64Shifted;
                    continue;
                }
                if (szWord == "Alignment") { pMobIndex.Alignment = Convert.ToInt32(rgsz[1]); continue; }
                if (szWord == "Alt_vnum") { pMobIndex.VnumAltersInto = Convert.ToInt32(rgsz[1]); continue; }
                if (szWord == "ArmorClass") { pMobIndex.Armcls = Convert.ToInt32(rgsz[1]); continue; }

                if (szWord == "ASklTaught")
                {
                    string[] rgSpl2 = rgsz[1].Split(spc, 2, StringSplitOptions.RemoveEmptyEntries);
                    int num = Convert.ToInt32(rgSpl2[0]);
                    int num2 = Convert.ToInt32(rgSpl2[1]);
                    if (num != 30) pMobIndex.Skltaught.Add(num2, num);
                    continue;
                }

                if (szWord == "BCasts")
                {
                    pMobIndex.CastSpells.Add(rgsz[1].TrimEnd('~'));
                    continue;
                }
                if (szWord == "BCast_P")
                {
                    pMobIndex.CastPercent = Convert.ToInt32(rgsz[1]);
                    continue;
                }
                if (szWord == "BKicks")
                {
                    pMobIndex.Kicks = Convert.ToInt32(rgsz[1]);
                    continue;
                }
                if (szWord == "BFlurries")
                {
                    pMobIndex.Flurries = Convert.ToInt32(rgsz[1]);
                    continue;
                }
                if (szWord == "BTackles")
                {
                    pMobIndex.Tackles = Convert.ToInt32(rgsz[1]);
                    continue;
                }
                if (szWord == "BWarrior_P")
                {
                    pMobIndex.WarriorPercent = Convert.ToInt32(rgsz[1]);
                    continue;
                }

                if (szWord == "Guard") { pMobIndex.MobGuards = Convert.ToInt32(rgsz[1]); continue; }
                if (szWord == "GHitR") { pMobIndex.ExtraHitroll = Convert.ToInt32(rgsz[1]); continue; }
                if (szWord == "GDamR") { pMobIndex.ExtraDamageroll = Convert.ToInt32(rgsz[1]); continue; }
                if (szWord == "GDod") { pMobIndex.ExtraDodgeBonus = Convert.ToInt32(rgsz[1]); continue; }
                if (szWord == "GPar") { pMobIndex.ExtraParryBonus = Convert.ToInt32(rgsz[1]); continue; }
                if (szWord == "Hp") { pMobIndex.Hpmult = Convert.ToInt32(rgsz[1]); continue; }
                if (szWord == "JPts") { pMobIndex.ObjCreationPoints = Convert.ToInt32(rgsz[1]); continue; }
                if (szWord == "JavO") { continue; } //pMobIndex.objImage[0] = (char)Convert.ToInt32(rgsz[1]); continue; }
                if (szWord == "JavT") { continue; } // pMobIndex.objImage[1] = (char)Convert.ToInt32(rgsz[1]); continue; }
                if (szWord == "MobType") { pMobIndex.Mobtype = (MobTypes)Convert.ToInt32(rgsz[1]); continue; }
                if (szWord == "Money") { pMobIndex.Money = Convert.ToInt32(rgsz[1]); continue; }
                if (szWord == "NHeight") { pMobIndex.Height = Convert.ToInt32(rgsz[1]); continue; }
                if (szWord == "Shopd2") { pMobIndex.PShop.Decrease = Convert.ToInt32(rgsz[1]); continue; }
                if (szWord == "Shopd3") { pMobIndex.PShop.Items_until_decrease = Convert.ToInt32(rgsz[1]); continue; }
                if (szWord == "ShopCr") { pMobIndex.PShop.Creates_vnum = Convert.ToInt32(rgsz[1]); continue; }
                if (szWord == "ShCrh") { pMobIndex.PShop.Creates_hours = Convert.ToInt32(rgsz[1]); continue; }
                if (szWord == "RaceHate") { pMobIndex.AttackRaces = Convert.ToInt32(rgsz[1]); continue; }
                if (szWord == "Sex") { pMobIndex.Sex = (Sex)Convert.ToInt32(rgsz[1]); continue; }
                if (szWord == "Name") { pMobIndex.Mobprototypename = rgsz[1].TrimEnd('~'); continue; }
                if (szWord == "Short") { pMobIndex.Short_descr = rgsz[1].TrimEnd('~'); continue; }
                if (szWord == "Level") { pMobIndex.Level = Convert.ToInt32(rgsz[1]); continue; }
                if (szWord == "Spec") // NYI HEREHERE
                {
                    pMobIndex.Spec_fun = rgsz[1].TrimEnd('~');
                    continue;
                }
                if (szWord == "ShopCS") { pMobIndex.PShop.Creates_message = rgsz[1].TrimEnd('~'); continue; }
                if (szWord == "Shop")
                {
                    ShopData pShop = new ShopData();
                    pShop.Keeper = vnum;
                    string[] rgSpl4 = rgsz[1].Split(spc, StringSplitOptions.RemoveEmptyEntries);
                    for (int iTrade = 0; iTrade < 5; iTrade++)
                        pShop.Buy_type.Add(Convert.ToInt32(rgSpl4[iTrade]));

                    pShop.Profit_buy = Convert.ToInt32(rgSpl4[5]);
                    pShop.Profit_sell = Convert.ToInt32(rgSpl4[6]);
                    pShop.Creates_hours = 1;
                    pShop.Open_hour = Convert.ToInt32(rgSpl4[7]);
                    pShop.Close_hour = Convert.ToInt32(rgSpl4[8]);
                    pShop.Decrease = 5;
                    pShop.Items_until_decrease = 4;
                    pShop.Creates_vnum = 0;
                    pShop.Creates_message = "";
                    pMobIndex.PShop = pShop;

                    EmlenMud.WorldTemplates.AllShops.Add(pShop);
                    continue;
                }

                if (szWord == "SFT")
                {
                    pMobIndex.script_fn = rgsz[1].TrimEnd('~');
                    continue;
                }

                if (szWord == "Long")
                {
                    StringBuilder sb = new StringBuilder(1024);

                    string szLine2 = sr.ReadLine();
                    while (szLine2.Trim() != "~")
                    {
                        sb.AppendLine(szLine2);
                        szLine2 = sr.ReadLine();
                    }
                    pMobIndex.Long_descr = sb.ToString();
                    continue;
                }


                if (szWord == "Descr")
                {
                    pMobIndex.Description = "";
                    string szLine2 = sr.ReadLine();
                    while (szLine2.Trim() != "~")
                    {
                        pMobIndex.Description += szLine2 + "\n\r";
                        szLine2 = sr.ReadLine();
                    }
                    continue;
                }
            }
            return;
        }

        public void WriteOldMobileFormat(StreamWriter sw, int vnum, MobPrototype mp, AreaData area)
        {
            MobPrototype pMobIndex = (MobPrototype)mp;
            char[] spc = new char[1];
            spc[0] = ' ';
            sw.WriteLine("#" + vnum.ToString());

            sw.WriteLine("Attackmsg " + pMobIndex.AttackName + "~");
            if (!string.IsNullOrEmpty(pMobIndex.GuardSect))
                sw.WriteLine("AClan2 " + pMobIndex.GuardSect);
            if (!string.IsNullOrEmpty(pMobIndex.GuardClan))
                sw.WriteLine("AClan " + pMobIndex.GuardClan);

            Int64 i64 = (Int64)pMobIndex.PrototypeBehaviors;
            Int64 actbits = ((i64 << 32) >> 32);
            Int64 actbits3 = (i64 >> 32);
            sw.WriteLine("ActBits " + actbits.ToString());
            sw.WriteLine("ActBits3 " + actbits3.ToString());
            sw.WriteLine("AYeller " + pMobIndex.Yeller_number.ToString());
            sw.WriteLine("AMax " + pMobIndex.MaxInWorld.ToString());
            sw.WriteLine("AWillhelp " + pMobIndex.Will_help.ToString());

            int actbits4 = 0;
            if ((pMobIndex.PrototypeBehaviors & ActionsAndBehavior.MOBSWITCH) != 0)
                actbits4 |= 0x00000800;
            if ((pMobIndex.PrototypeBehaviors & ActionsAndBehavior.FASTHUNT) != 0)
                actbits4 |= 0x00001000;
            if ((pMobIndex.PrototypeBehaviors & ActionsAndBehavior.SOLOYELL) != 0)
                actbits4 |= 0x00002000;
            if ((pMobIndex.PrototypeBehaviors & ActionsAndBehavior.STAYOFFROAD) != 0)
                actbits4 |= 0x00004000;
            if ((pMobIndex.PrototypeBehaviors & ActionsAndBehavior.KILLALLONE) != 0)
                actbits4 |= 0x00008000;
            if ((pMobIndex.PrototypeBehaviors & ActionsAndBehavior.KILLALLTWO) != 0)
                actbits4 |= 0x00010000;
            if ((pMobIndex.PrototypeBehaviors & ActionsAndBehavior.KILLMEVIL) != 0)
                actbits4 |= 0x00020000;
            if ((pMobIndex.PrototypeBehaviors & ActionsAndBehavior.KILLMGOOD) != 0)
                actbits4 |= 0x00040000;
            sw.WriteLine("ActBits4 " + actbits4.ToString());

            Int64 aff1 = ((((Int64)pMobIndex.PrototypeEffects) << 32) >> 32);
            Int64 aff2 = (((Int64)pMobIndex.PrototypeEffects) >> 32);
            sw.WriteLine("Affect_By " + aff1.ToString());
            sw.WriteLine("AffectTWO " + aff2.ToString());

            sw.WriteLine("Alignment " + pMobIndex.Alignment.ToString());
            sw.WriteLine("Alt_vnum " + pMobIndex.VnumAltersInto.ToString());
            sw.WriteLine("ArmorClass " + pMobIndex.Armcls.ToString());
            int nSkl = 0;
            foreach (var de in pMobIndex.Skltaught)
            {
                sw.WriteLine("ASkltTaught " + nSkl.ToString() + " " + de.Value.ToString());
                nSkl++;
            }
            if (pMobIndex.CastSpells.Count > 0)
            {
                sw.WriteLine("BCasts " + pMobIndex.CastSpells[0].ToString() + "~");
                sw.WriteLine("BCast_P " + pMobIndex.CastPercent.ToString());
            }
            if (pMobIndex.Kicks > 0) sw.WriteLine("BKicks " + pMobIndex.Kicks.ToString());
            if (pMobIndex.Flurries > 0) sw.WriteLine("BFlurries " + pMobIndex.Flurries.ToString());
            if (pMobIndex.Tackles > 0) sw.WriteLine("BTackles " + pMobIndex.Tackles.ToString());
            if (pMobIndex.WarriorPercent > 0) sw.WriteLine("BWarrior_P " + pMobIndex.WarriorPercent.ToString());
            if (pMobIndex.MobGuards > 0) sw.WriteLine("Guard " + pMobIndex.MobGuards.ToString());
            if (pMobIndex.ExtraHitroll != 0) sw.WriteLine("GHitR " + pMobIndex.ExtraHitroll.ToString());
            if (pMobIndex.ExtraDamageroll != 0) sw.WriteLine("GDamR " + pMobIndex.ExtraDamageroll.ToString());
            if (pMobIndex.ExtraDodgeBonus != 0) sw.WriteLine("GDod " + pMobIndex.ExtraDodgeBonus.ToString());
            if (pMobIndex.ExtraParryBonus != 0) sw.WriteLine("GPar " + pMobIndex.ExtraParryBonus.ToString());
            if (pMobIndex.Hpmult != 0) sw.WriteLine("Hp " + pMobIndex.Hpmult.ToString());
            if (pMobIndex.ObjCreationPoints != 0) sw.WriteLine("JPts " + pMobIndex.ObjCreationPoints.ToString());
            if (pMobIndex.Mobtype != 0) sw.WriteLine("MobType " + ((int)pMobIndex.Mobtype).ToString());
            if (pMobIndex.Money != 0) sw.WriteLine("Money " + pMobIndex.Money.ToString());
            if (pMobIndex.Height != 0) sw.WriteLine("NHeight " + pMobIndex.Height.ToString());
            if (pMobIndex.PShop != null)
            {
                sw.Write("Shop " + pMobIndex.PShop.Keeper.ToString());

                for (int iTrade = 0; iTrade < 5; iTrade++)
                {
                    if (pMobIndex.PShop.Buy_type.Count > iTrade)
                    {
                        sw.Write(" " + pMobIndex.PShop.Buy_type[iTrade].ToString());
                    }
                    else
                    {
                        sw.Write(" 0");
                    }
                }

                sw.Write(" " + pMobIndex.PShop.Profit_buy.ToString());
                sw.Write(" " + pMobIndex.PShop.Profit_sell.ToString());
                sw.Write(" " + pMobIndex.PShop.Open_hour.ToString());
                sw.WriteLine(" " + pMobIndex.PShop.Close_hour.ToString());

                sw.WriteLine("Shopd2 " + pMobIndex.PShop.Decrease.ToString());
                sw.WriteLine("Shopd3 " + pMobIndex.PShop.Items_until_decrease.ToString());
                sw.WriteLine("ShopCr " + pMobIndex.PShop.Creates_vnum.ToString());
                sw.WriteLine("ShCrh " + pMobIndex.PShop.Creates_hours.ToString());
                if (!string.IsNullOrEmpty(pMobIndex.PShop.Creates_message))
                    sw.WriteLine("ShopCS " + pMobIndex.PShop.Creates_message + "~");

            }

            sw.WriteLine("RaceHate " + pMobIndex.AttackRaces.ToString());
            sw.WriteLine("Sex " + ((int)pMobIndex.Sex).ToString());
            sw.WriteLine("Name " + pMobIndex.Mobprototypename.ToString() + "~");
            sw.WriteLine("Short " + pMobIndex.Short_descr.ToString() + "~");
            sw.WriteLine("Level " + pMobIndex.Level.ToString());

            if (!string.IsNullOrEmpty(pMobIndex.Spec_fun))
                sw.WriteLine("Spec " + pMobIndex.Spec_fun);

            if (!string.IsNullOrEmpty(pMobIndex.Script_fn))
                sw.WriteLine("SFT " + pMobIndex.Script_fn);

            sw.WriteLine("Long");
            sw.WriteLine(pMobIndex.Long_descr);
            sw.WriteLine("~");

            sw.WriteLine("Descr");
            sw.WriteLine(pMobIndex.Description);
            sw.WriteLine("~");

            sw.WriteLine("End");
            sw.WriteLine("");
        }


        public void save_mobiles_old_format(StreamWriter sw, AreaData area)
        {
            for (int n = 0; n < area.MobPrototypesBelongingToArea.Count; n++)
            {
                MobPrototype mp = (MobPrototype)area.MobPrototypesBelongingToArea[n];
                sw.WriteLine("#" + mp.Vnum.ToString());
                WriteOldMobileFormat(sw, mp.Vnum, mp, area);
            }
        }

        // something about saving the mobs isn't working
        public void load_mobiles_old_format(StreamReader sr, AreaData area)
        {
            area.TotalMobPrototypes = 0;
            while (sr.EndOfStream == false)
            {
                int vnum;
                char c = ' ';
                while (c != '#' && sr.EndOfStream == false) c = (char)sr.Read();
                if (c != '#')
                {
                    Debug.WriteLine("Area " + area.ShortName + " possibly corrupt?  No # on the load_mobiles section...");
                    EmlenMud.LogError("Area " + area.ShortName + " possibly corrupt?  No # on the load_mobiles section...", null, LogType.WorldError);
                    break;
                }

                vnum = Convert.ToInt32(sr.ReadLine().Trim());
                if (vnum == 0) break;
                if (EmlenMud.WorldTemplates.AllMobPrototypes.ContainsKey(vnum) == true)
                {
                    EmlenMud.LogError("Load_mobiles: vnum " + vnum.ToString() + " duplicated in area " + area.ShortName, null, LogType.WorldError);
                    continue;
                }

                ReadOldMobileFormat(sr, vnum, area);
                area.TotalMobPrototypes++;
                if (vnum > EmlenMud.WorldTemplates.top_vnum_mob_prototype) EmlenMud.WorldTemplates.top_vnum_mob_prototype = vnum;

            }
        }
    }
}
